#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#include "config.h"
#include "aux_types.h"
#include "aux_string.h"
#include "aux_errno.h"

#ifdef PLATFORM_WIN
#include "win_str.h"
#endif


size_t aux_strlcpy(char *dest, const char *src, size_t size)
{
    size_t ret = strlen(src);

    if (size)
    {
        size_t len = (ret >= size) ? size - 1 : ret;
        memcpy(dest, src, len);
        dest[len] = '\0';
    }

    return ret;
}

EErrNo aux_memcpy_each_byte(u8 *pbyDest, const u8 *pbySrc, u32 nByteCnt)
{
    u8 *d;
    const u8 *s;

    if (!pbyDest || !pbySrc)
        return -ERRNO_EPARAMETER_INVALID;

    if (0 == nByteCnt)
        return ERRNO_SUCCESS;

    if (pbyDest == pbySrc)
        return ERRNO_SUCCESS;

    if (pbyDest > (pbySrc + nByteCnt) ||
        pbySrc  > (pbyDest + nByteCnt))
    {
        memcpy(pbyDest, pbySrc, nByteCnt);
    }
    else if (pbyDest < pbySrc)
    {
        d = pbyDest;
        s = pbySrc;
        while (nByteCnt--)
            *d++ = *s++;
    }
    else /* overlap */
    {
        d = (u8 *)(pbyDest + nByteCnt - 1);
        s = (u8 *)(pbySrc + nByteCnt -1);
        while (nByteCnt --)
            *d-- = *s--;
    }

 return ERRNO_SUCCESS;
}


char *aux_strerror(EErrNo eNo)
{
    switch (eNo)
    {
        case ERRNO_SUCCESS:
            return "false or success or valid";
        case ERRNO_INVALID:
            return "invalid";
        case ERRNO_FAIL:
            return "fail";
        case ERRNO_TRUE:
            return "true";
        case ERRNO_EWRONG:
            return "wrong";
        case ERRNO_EFATAL_MUTEX_UNLOCK:
            return "mutex unlock fatal error";
        case ERRNO_EPARAMETER_INVALID:
            return "invalid parameter";
        case ERRNO_EINIT_LOCK_FAIL:
            return "init lock fail";
        case ERRNO_ELOCK_FAIL:
            return "lock fail";
        case ERRNO_EUNLOCK_FAIL:
            return "unlock fail";
        case ERRNO_EINVALID_MUTEX:
            return "invalid lock";
        case ERRNO_EMALLOC_FAIL:
            return "malloc fail";
        default:
            return "";
    }

    /* unreachable */
    return "";
}


